name: Build Drogon

on:
  push:
    branches: [ master ]
  pull_request:
  workflow_dispatch:

env:
  # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
  BUILD_TYPE: Release

jobs:
  windows:
    name: windows/msvc - ${{ matrix.link }}
    runs-on: windows-2019
    strategy:
      fail-fast: false
      matrix:
        link: [ 'STATIC', 'SHARED' ]
    steps:
      - name: Checkout Drogon source code
        uses: actions/checkout@v2
        with:
          submodules: true
          fetch-depth: 0

      - name: Install dependencies
        run: pip install conan

      - name: Create build directory
        run: mkdir build

      - name: Install conan packages
        working-directory: ./build
        run: |
          conan profile detect
          conan install .. -s compiler="msvc" -sbuild_type=Debug --build=missing -s compiler.cppstd=17

      - name: Create Build Environment & Configure Cmake
        shell: bash
        working-directory: ./build
        run: |
          [[ ${{ matrix.link }} == "SHARED" ]] && shared="ON" || shared="OFF"
          cmake ..                                         \
            -DCMAKE_BUILD_TYPE=Debug                       \
            -DBUILD_TESTING=on                             \
            -DBUILD_SHARED_LIBS=$shared                    \
            -DCMAKE_TOOLCHAIN_FILE="conan_toolchain.cmake" \
            -DBUILD_CTL=ON                                 \
            -DBUILD_EXAMPLES=ON                            \
            -DCMAKE_INSTALL_PREFIX=../install              \
            -DCMAKE_POLICY_DEFAULT_CMP0091=NEW             \
            -DCMAKE_CXX_STANDARD=17

      - name: Build
        run: cmake --build build --target install --parallel

      - name: Test
        shell: bash
        run: ./test.sh -w

  unix:
    name: ${{ matrix.buildname }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-20.04
            buildname: 'ubuntu-20.04/gcc'
            link: SHARED
            triplet: x64-linux
            compiler: gcc_64
          - os: ubuntu-20.04
            buildname: 'ubuntu-20.04/gcc'
            link: STATIC
            triplet: x64-linux
            compiler: gcc_64
          - os: ubuntu-20.04
            buildname: 'ubuntu-20.04/gcc-10'
            link: STATIC
            triplet: x64-linux
          - os: ubuntu-20.04
            buildname: 'ubuntu-20.04/c++14'
            link: STATIC
            triplet: x64-linux
            compiler: gcc_64
          - os: macos-latest
            buildname: 'macos/clang'
            link: STATIC
            triplet: x64-osx
            compiler: clang_64
    steps:
    - name: Checkout Drogon source code
      uses: actions/checkout@v2
      with:
        submodules: true
        fetch-depth: 0

    - name: (macOS) Install dependencies
      if: runner.os == 'macOS'
      run: |
        brew install jsoncpp brotli zlib
        brew install lz4 mariadb sqlite3 postgresql hiredis
        brew install redis

    - name: (Linux) Install dependencies
      if: runner.os == 'Linux'
      run: |
        # Installing packages might fail as the github image becomes outdated
        sudo apt update
        # These aren't available or don't work well in vcpkg
        sudo apt-get install -y libjsoncpp-dev uuid-dev libssl-dev zlib1g-dev libsqlite3-dev
        sudo apt-get install -y libbrotli-dev
    - name: (Linux) Install gcc-10
      if: matrix.buildname == 'ubuntu-20.04/gcc-10'
      run: sudo apt-get install -y gcc-10 g++-10
    - name: (Linux) Install boost
      if: matrix.buildname == 'ubuntu-20.04/c++14'
      run: |
        sudo apt-get update
        sudo apt-get -y install libboost-all-dev

    - name: (Linux) Install postgresql
      if: matrix.os == 'ubuntu-20.04'
      run: sudo apt-get -y install postgresql-all

    - name: Export `shared`
      run: |
        [[ ${{ matrix.link }} == "SHARED" ]] && shared="ON" || shared="OFF"
        echo "shared=$shared" >> $GITHUB_ENV

    - name: Create Build Environment & Configure Cmake
      # Some projects don't allow in-source building, so create a separate build directory
      # We'll use this as our working directory for all subsequent commands
      if: matrix.buildname != 'ubuntu-20.04/gcc-10' && matrix.buildname != 'ubuntu-20.04/c++14'
      run: |
        cmake -B build                   \
          -DCMAKE_BUILD_TYPE=$BUILD_TYPE \
          -DBUILD_TESTING=on             \
          -DBUILD_SHARED_LIBS=$shared

    - name: Create Build Environment & Configure Cmake (gcc-10)
      # Some projects don't allow in-source building, so create a separate build directory
      # We'll use this as our working directory for all subsequent commands
      if: matrix.buildname == 'ubuntu-20.04/gcc-10'
      run: |
        cmake -B build                     \
          -DCMAKE_BUILD_TYPE=$BUILD_TYPE   \
          -DBUILD_TESTING=on               \
          -DCMAKE_CXX_FLAGS="-fcoroutines" \
          -DBUILD_SHARED_LIBS=$shared
      env:
        CC: gcc-10
        CXX: g++-10

    - name: Create Build Environment & Configure Cmake (C++14)
      # Some projects don't allow in-source building, so create a separate build directory
      # We'll use this as our working directory for all subsequent commands
      if: matrix.buildname == 'ubuntu-20.04/C++14'
      run: |
        cmake -B build                   \
          -DCMAKE_BUILD_TYPE=$BUILD_TYPE \
          -DBUILD_TESTING=on             \
          -DCMAKE_CXX_STANDARD=14        \
          -DBUILD_SHARED_LIBS=$shared

    - name: Build
      working-directory: ./build
      # Execute the build.  You can specify a specific target with "--target <NAME>"
      run: make -j $(nproc) && sudo make install

    - name: (macOS) Prepare for testing
      if: runner.os == 'macOS'
      run: |
        cd $(brew --prefix)/Homebrew/Library/Taps/homebrew/homebrew-services
        cd ~
        brew tap homebrew/services
        brew services restart postgresql
        brew services start mariadb
        brew services start redis
        sleep 4
        mariadb -e "SET PASSWORD FOR 'root'@'localhost' = PASSWORD('')"
        mariadb -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost'"
        mariadb -e "FLUSH PRIVILEGES"
        brew services restart mariadb
        sleep 4
        psql -c 'create user postgres superuser;' postgres

    - name: (Linux) Prepare for testing
      if: runner.os == 'Linux'
      run: |
        sudo systemctl start postgresql
        sleep 1
        sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '12345'" postgres

    - name: Test
      # Execute tests defined by the CMake configuration.
      # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
      run: ./test.sh -t

    - name: Lint
      if: matrix.os == 'ubuntu-20.04'
      run: |
        sudo apt install -y dos2unix
        ./format.sh && git diff --exit-code
